import re
# \s 表示任意的空白字符等价于[\f\n\r\t\v]
print(re.search(r'\s', 'hello world')) # 空格     # <re.Match object; span=(5, 6), match=' '>
print(re.search(r'\s', 'hello\nworld')) # 换行    # <re.Match object; span=(5, 6), match='\n'>
print(re.search(r'\s', 'hello\tworld')) # 制表符  # <re.Match object; span=(5, 6), match='\t'>

# \S 表示任意的非空白字符
print(re.search(r'\S', '\t\n    x')) # 空格       # <re.Match object; span=(6, 7), match='x'>

# 标点符号的使用
# ()标记一个子表达式的开始和结束位置，用来表示一个分组
m = re.search(r'h(\d+)x', 'sh829xkflsa')
print(m.group())    # h829x
print(m.group(1))   # 829
m1 = re.search(r'(.*)', '(1+1)*3+5')
print(m1.group())   # (1+1)*3+5
# 如果要表示括号，需要使用 \
m11 = re.search(r'\(.*\)', '(1+1)*3+5')
print(m11.group())   # (1+1)

# . 表示匹配除了换行以外的任意字符。如果想要匹配 . 需要使用 \.

# [] 用来表示可选项范围  [x-y]从x-y区间，包含x和y
m2 = re.search(r'f[0-5]m', 'pdsf6m')
print(m2)   # None
m21 = re.search(r'f[0-5]m', 'pdsf5m')   # 只匹配一次
print(m21)  # <re.Match object; span=(3, 6), match='f5m'>
m22 = re.search(r'f[0-5a-dx]m', 'pdsfcm')   # 空括号里或者关系，只匹配一次,0<=values<=5 或者 a<=values<=d 或者values=x
print(m22)  # <re.Match object; span=(3, 6), match='fcm'>
m23 = re.search(r'f[0-5]+m', 'pdsf5034m') # + 一次或多次
print(m23)  # <re.Match object; span=(3, 9), match='f5034m'>

# | 用来表示或者 和 [] 有一定的相似，但是有区别
# [] 里的值表示的区间，而且是单个字符
# | 就是可选值，可以出现多个值
print(re.search(r'f(x|pr|t)m', 'pdsfprm'))  # <re.Match object; span=(3, 7), match='fprm'>

# {} 用来限定前面元素出现的次数
# {n}:表示前面的元素出现n 次
print(re.search(r'go{2}d', 'good'))     # <re.Match object; span=(0, 4), match='good'>
# {n,}:表示前面的元素出现n 次以上，包括n 次
print(re.search(r'go{2,}d', 'good'))    # <re.Match object; span=(0, 4), match='good'>
print(re.search(r'go{2,}d', 'god'))     # None
print(re.search(r'go{2,}d', 'goooood')) # <re.Match object; span=(0, 7), match='goooood'>
# {，n}:表示前面的元素出现n 次以下，包括n 次
print(re.search(r'go{,2}d', 'good'))     # <re.Match object; span=(0, 3), match='god'>
print(re.search(r'go{,2}d', 'goood'))     # None
print(re.search(r'go{,2}d', 'god'))      # <re.Match object; span=(0, 3), match='god'>
print(re.search(r'go{,2}d', 'gd'))       # <re.Match object; span=(0, 3), match='gd'>
# {m,n}:表示前面的元素出现m到n次，包括m和n
print(re.search(r'go{3,5}d', 'good'))   # None
print(re.search(r'go{3,5}d', 'goood'))  # <re.Match object; span=(0, 5), match='goood'>
print(re.search(r'go{3,5}d', 'goooood'))    # <re.Match object; span=(0, 7), match='goooood'>

# * : 表示前面的元素出现任意次数（0次及以上） 等价于 {0,}
print(re.search(r'go*d', 'gd')) # <re.Match object; span=(0, 2), match='gd'>
print(re.search(r'go*d', 'good'))    # <re.Match object; span=(0, 35), match='good'>

# + : 表示前面的元素至少出现一次，等价于 {1,}
print(re.search(r'go+d', 'gd')) # None
print(re.search(r'go+d', 'good'))   # <re.Match object; span=(0, 4), match='good'>

# ? : 两种用法：
# 1.规定前面的元素最多只能出现一次，等价于 {,1}
# 2.将贪婪模式转换成为非贪婪模式
print(re.search(r'go?d', 'god'))    # <re.Match object; span=(0, 3), match='god'>
print(re.search(r'go?d', 'good'))    # None

# ^:已指定的内容开头  $:已指定的内容结尾
print(re.search(r'^ai$', 'dsfsodihaofdi'))  # None
print(re.search(r'^a.*i$', 'aofdi'))  # <re.Match object; span=(0, 5), match='aofdi'>
print(re.search(r'^a.*i$', 'dsa\naofdi\nsdasdasds', re.M))  # <re.Match object; span=(0, 5), match='aofdi'>














